#include "../LibCommon/EagleDefine.h"
#include "CameraPlugin.h"
#include "iostream"
#include <map>
#include <string>
#include <mutex>
#include <algorithm>
#ifndef __LINUX__
#include <Windows.h>
#endif
#include "../LibCommon/DllLoader.h"

using namespace std;

class DllCameraPlugin :public CameraPlugin
{
public:
	DllCameraPlugin(const std::wstring& modname);
	virtual ~DllCameraPlugin();

	std::vector<CameraInterface*>& GetSupportInterface();
	std::wstring &GetError();
	virtual bool Inited();
	virtual void Close();
	virtual bool Connect(int device_id = -1, int ccd_serial = -1, string mode = "full");
	virtual void DisConnect();
	virtual std::string GetEndCode();
	virtual std::string GetStartCode();
	virtual long GetSerialRate();
	virtual bool AddInterface(CameraInterface *_interface);
private:
	PluginProc m_proc;
	//HMODULE m_hmod;
	CDllLoader m_loader;
	CameraPlugin *m_plugin;

	std::wstring _err;
public:
	wstring map_key;
};

std::wstring GetCameraBasic(CameraPlugin *plugin);

class CameraPluginMgr
{
private:
	CameraPluginMgr();
	CameraPluginMgr(const CameraPluginMgr&){}
	CameraPluginMgr& operator=(const CameraPluginMgr&){}
	~CameraPluginMgr();

	int RescanPlugins();
public:
	static CameraPluginMgr* getInstance()
	{
		static CameraPluginMgr _instance;
		return &_instance;
	}

	std::map<wstring, CameraPlugin*>& GetAllCameras() { return cameras; }

	CameraPlugin *GetCamera(wstring key){
		try{
			return cameras.at(key);
		} catch (std::out_of_range&){
			return NULL;
		}
	}

private:
	std::map<wstring, CameraPlugin*> cameras;
};